﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using CKS.API.Exceptions;
using CKS.API.Logging;
using CKS.API.Contracts;
using System.Collections.Generic;

namespace CKSInstrumentationFarmTest.FarmTestWP
{
    [ToolboxItemAttribute(false)]
    public class FarmTestWP : WebPart
    {
        CKSFarmLogger logger = new CKSFarmLogger(SPContext.Current.Site.RootWeb, false);
        Guid timer = Guid.Empty;

        protected override void OnInit(EventArgs e)
        {
            logger.CatchUnhandledExceptions();
            base.OnInit(e);
        }





        void Bad_Click(object sender, EventArgs e)
        {
            //Simulate a situation the user must know about (i.e unable to save an item) and be more "in their face" about it
            //Also demonstrates variable dumping when an error occurs

            //The following line will be removed from our Release builds automatically
            logger.WriteDebugMethodStart();

            SPList list = null;
            //a couple of variables we're not really using, except to demonstrate variable dumping
            int myInt = 5;
            string myString = "hello World";




            try
            {
                list = SPContext.Current.Site.RootWeb.Lists.TryGetList("Announcements");
                if (Check.ThatIsNotNull(list))
                {
                    SPListItem itm = list.AddItem();
                    itm["Title"] = "Hello World";
                    itm["Body"] = "12345";
                    //error thrown here - field doesn't exist
                    itm["NonExistantField"] = "blah";
                    itm.Update();
                }
            }
            catch (Exception ex)
            {
                //handle the exception
                logger.HandleException(new CKSExceptionDetails(ex, CKSLoggingCategory.ListItem)
                {
                    Display = ErrorDisplayType.Dialog,
                    ThrowingControl = this
                });
                //Dump variables - this call will be removed from the Release build.
                //To dump vaiables in Release build, use "DumpVariablesInRelease"

                logger.DumpVariablesInDebug(new List<CKSVariableWrapper>()
                    {
                        new CKSVariableWrapper("list", list, "Title","ItemCount", "CanReceiveEmail" ),
                        new CKSVariableWrapper("intVar", myInt),
                        new CKSVariableWrapper("stringVar", myString)
                    });
            }
            finally
            {
                //The following line will be removed from our Release builds automatically
                logger.WriteDebugMethodEnd();
            }
        }

        void ReallyBad_Click(object sender, EventArgs e)
        { //Simulate an *unhandled* exception i.e. a site was deleted or incorrect URL specified

            try
            {

                logger.WriteDebugMethodStart();

                using (SPSite siteCollection = new SPSite(InvalidUrl)) // <-- Error thrown here but not caught
                {
                    //Do something
                    //Works fine if a valid URL is used, fails if not

                }
            }
            finally
            {
                //The following line will be removed from our Release builds automatically
                logger.WriteDebugMethodEnd();
            }
        }



        void Timings_Click(object sender, EventArgs e)
        {
            // An example of tracking how long a block of code takes to run.  
            // In a Farm environment, this could also be written to the Developer Dashboard by using SPMonitoredScope

            
            logger.Monitor("Do Some Stuff", DoSomeStuff);

            //If we don't have a delegate defined that matches our call, or are in the sandbox:
            //timer = logger.WriteElapsedTimeStart("Random Delay");
            //DoSomeOtherStuff(string myString, SPList myList);
            //logger.WriteElapsedTimeStop(timer);

        }



        private static void DoSomeStuff()
        {
            SPList list = null;
            int counter = 0;

            //perform a random number of SP operations just to kill some time
            for (int i = 0; i < new Random().Next(10, 15); i++)
            {
                list = SPContext.Current.Web.Lists.TryGetList("Announcements");
                if (Check.ThatIsNotNull(list))
                {
                    counter = list.ItemCount;
                }
            }
        }
        #region Sandbox Demo
        //temporarily removed

        //void NoBigDeal_Click(object sender, EventArgs e)
        //{

        //    //Simulate a situation we can recover from
        //    //(i.e. an inaccessible configuration setting for which a default value is available)

        //    logger.WriteDebugMethodStart();
        //    logger.WriteDebug("This is a message that won't show up in Release mode!");

        //    string configSetting = GetConfigSettingOrDefault("mySetting");



        //    logger.WriteDebugMethodEnd();
        //}

        //private string GetConfigSettingOrDefault(string p)
        //{
        //    logger.WriteDebugMethodStart();
        //    //Try to get setting here...

        //    logger.Write(string.Format("Configuration Setting {0} is not available", p), CKSLoggingCategory.General, LoggingSeverity.Warning);
        //    logger.WriteDebugMethodEnd();
        //    return "Default Setting Value";
        //}

        //void NotSoBad_Click(object sender, EventArgs e)
        //{

        //    //Simulate a situation the user should be told about
        //    //(i.e. error retrieving some list items)
        //    try
        //    {
        //        logger.WriteDebugMethodStart();
        //        SPList list = SPContext.Current.Site.RootWeb.Lists.TryGetList("Announcements");
        //        SPListItem itm = list.GetItemById(5);
        //        itm["Title"] = "Hello World";
        //        itm.Update();


        //    }
        //    catch (Exception ex)
        //    {
        //        logger.HandleException(new CKSExceptionDetails(ex, CKSLoggingCategory.List)
        //        {
        //            Display = ErrorDisplayType.StatusBar,
        //            ThrowingControl = this,
        //            UserText = "Item Title NOT Updated!",
        //            StatusBarColor = CKSStatusBarColor.red
        //        });

        //    }
        //    finally
        //    {

        //        logger.WriteDebugMethodEnd();
        //    }
        //}
        #endregion


        #region Set Up UI

        private string _invalidUrl = "http://invalid_url";

        public enum ErrorType
        {
            All,
            ReallyBad,
            Bad,
            NotSoBad,
            NoBigDeal
        }

        [WebBrowsable(true),
        WebDisplayName("Type of Error"),
        Personalizable(PersonalizationScope.Shared),
        Category("CKS:API")]
        public ErrorType TypeOfError { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Invalid URL for use with 'Really Bad Thing' error"),
        Personalizable(PersonalizationScope.Shared),
        Category("CKS:API")]
        public string InvalidUrl
        {
            get
            {
                return _invalidUrl;
            }
            set
            {
                _invalidUrl = value;
            }
        }



        protected override void CreateChildControls()
        {
            Controls.Add(new LiteralControl("<span style='font-size:large;text-decoration:underline'>Farm</span><br /><br />"));


            if (TypeOfError == ErrorType.All || TypeOfError == ErrorType.ReallyBad)
            {
                Button ReallyBad = new Button()
                {
                    Text = "Simulate an unhandled exception"
                };
                ReallyBad.Click += new EventHandler(ReallyBad_Click);
                Controls.Add(ReallyBad);
                Controls.Add(new LiteralControl("&nbsp;&nbsp;<span style='font-size:smaller'>(Things have gone really wrong)</span><br /><br />"));
            }

            if (TypeOfError == ErrorType.All || TypeOfError == ErrorType.Bad)
            {
                Button Bad = new Button()
                {
                    Text = "In the User's Face"
                };

                Bad.Click += new EventHandler(Bad_Click);
                Controls.Add(Bad);
                Controls.Add(new LiteralControl("&nbsp;&nbsp;<span style='font-size:smaller'>(Simulate a situation the user must know about)</span><br /><br />"));
            }

            #region Sandbox Demo
            //temporarily removed
            //if (TypeOfError == ErrorType.All || TypeOfError == ErrorType.NotSoBad)
            //{
            //    Button NotSoBad = new Button()
            //    {
            //        Text = "Not So Bad"
            //    };

            //    NotSoBad.Click += new EventHandler(NotSoBad_Click);
            //    Controls.Add(NotSoBad);
            //    Controls.Add(new LiteralControl("&nbsp;&nbsp;<span style='font-size:smaller'>(Simulate a situation the user should be told about, but we don't need to be quite so obnoxious about it)</span><br /><br />"));
            //}

            //if (TypeOfError == ErrorType.All || TypeOfError == ErrorType.NoBigDeal)
            //{
            //    Button NoBigDeal = new Button()
            //    {
            //        Text = "Handle, Log and Continue"
            //    };

            //    NoBigDeal.Click += new EventHandler(NoBigDeal_Click);
            //    Controls.Add(NoBigDeal);
            //    Controls.Add(new LiteralControl("&nbsp;&nbsp;<span style='font-size:smaller'>(Simulate a situation we can recover from)</span><br /><br />"));
            //}
            #endregion

            Button Timings = new Button()
            {
                Text = "Metrics"

            };
            Timings.Click += new EventHandler(Timings_Click);

            Controls.Add(Timings);




        }

        #endregion

    }




}
